import { HttpException, HttpStatus, Injectable } from '@nestjs/common';
import IResponse from '@/services/response.service';
import * as puppeteer from "puppeteer";
import * as path from "path";
import * as fs from "fs-extra";
import IConstants from "@/core/constants";
import IHelper from "@/services/helper.service";
import {ConfigService} from "@nestjs/config";
import {ReqProvider} from "@/core/providers/req.provider";
import { defer, map, concatMap, timeout, catchError, of, Observable, forkJoin, tap, concat, reduce } from 'rxjs';
import { PubTaskEntity } from '@/db/entitys/pub-task.entity';
import { AccountEntity } from '@/db/entitys/account.entity';
import { VideoEntity } from '@/db/entitys/video.entity';
import { IWonewSer } from '@/typing';
import { KsBindService } from './ks.bind.service';
import axios, { RawAxiosRequestHeaders } from 'axios';
import * as FileType from "file-type"
import * as FromData from "form-data"
import { DbService } from '@/db/db.service';
import ks_typelistJSon from "./json/ks_typelist.json"
import ILogger from '@/services/logger.service';

@Injectable()
export class KsService {
  constructor(
    private readonly reqProvider: ReqProvider,
    private readonly ksBindService: KsBindService,
    private readonly dbService: DbService,
  ) {
  }

  // https://www.52pojie.cn/thread-1374678-1-1.html
  publishVideoToAccount(taskSchema: PubTaskEntity, accountSchema: AccountEntity, videoSchema: VideoEntity): Observable<IWonewSer.PublishTaskResult> {
    const task: IWonewSer.KsPublishTask = {
      uuid: `发布[${videoSchema.name}]到账号[${accountSchema.name}]`,
      startAt: Date.now(),
      taskSchema, accountSchema, videoSchema, 
      videoBuffer: fs.readFileSync(IHelper.getAssetAbsPathByStaticPath(videoSchema.video)),
      coverBuffer: fs.readFileSync(IHelper.getAssetAbsPathByStaticPath(videoSchema.cover)),
      res_uploadCover: {},
      res_uploadVideo: {}
    }
    // @ts-ignore
    return this.ksBindService.checkCookie(accountSchema.cookie).pipe(
      map(res => {
        if (!res.valid) {
          ILogger.info(`Bili cookie expired.`)
          throw new HttpException("Bili cookie expired.", HttpStatus.BAD_REQUEST)
        }
        return task
      }),
      tap(() => ILogger.info(`${task.uuid} start getVideoFiletype`)),
      concatMap(() => this.getVideoFiletype(task)),
      tap(() => ILogger.info(`${task.uuid} start uploadVideo_pre`)),
      concatMap(() => this.uploadVideo_pre(task)),
      tap(() => ILogger.info(`${task.uuid} start uploadVideo_resume`)),
      concatMap(() => this.uploadVideo_resume(task)),
      tap(() => ILogger.info(`${task.uuid} start uploadVideo_upload`)),
      concatMap(() => this.uploadVideo_upload(task)),
      tap(() => ILogger.info(`${task.uuid} start uploadVideo_complete`)),
      concatMap(() => this.uploadVideo_complete(task)),
      tap(() => ILogger.info(`${task.uuid} start uploadVideo_finish`)),
      concatMap(() => this.uploadVideo_finish(task)),
      tap(() => ILogger.info(`${task.uuid} start uploadCover_upload`)),
      concatMap(() => this.uploadCover_upload(task)),
      tap(() => ILogger.info(`${task.uuid} start publishVideo`)),
      concatMap(() => this.publishVideo(task)),
      tap(() => ILogger.info(`${task.uuid} end publishVideo`)),
      map(() => {
        const {videoBuffer, coverBuffer, ...rest} = task
        return {status: true, message: "success", resp: rest}
      }),
      catchError(error => {
        const {videoBuffer, coverBuffer, ...rest} = task
        return of({status: false, message: error.message, resp: rest})
      })
    )
  }
  getApiPh(task: IWonewSer.KsPublishTask): string {
    const cookies: puppeteer.Protocol.Network.Cookie[] = JSON.parse(task.accountSchema.cookie)
    return cookies.find(e => e.name === "kuaishou.web.cp.api_ph")?.value || ""
  }
  getVideoFiletype(task: IWonewSer.KsPublishTask) {
    return defer(() => 
      FileType.fromFile(IHelper.getAssetAbsPathByStaticPath(task.videoSchema.video))
    ).pipe(
      map(res => {
        task.videoFiletype = res
        return task
      })
    )
  }
  uploadVideo_pre(task: IWonewSer.KsPublishTask) {
    return defer(() => 
      axios.post(
        'https://cp.kuaishou.com/rest/cp/works/v2/video/pc/upload/pre',
        {
          'uploadType': 1,
          'kuaishou.web.cp.api_ph': this.getApiPh(task)
        },
        {
          headers: {
            'Accept': '*/*',
            'Accept-Language': 'zh-CN,zh;q=0.9',
            'Cache-Control': 'no-cache',
            'Connection': 'keep-alive',
            'Content-Type': 'application/json;charset=UTF-8',
            'Cookie': IHelper.covert2StandardCookieStr(task.accountSchema.cookie),
            'Origin': 'https://cp.kuaishou.com',
            'Pragma': 'no-cache',
            'Referer': 'https://cp.kuaishou.com/article/publish/video',
            'Sec-Fetch-Dest': 'empty',
            'Sec-Fetch-Mode': 'cors',
            'Sec-Fetch-Site': 'same-origin',
            'User-Agent': 'Mozilla/5.0 (Macintosh; Intel Mac OS X 10_15_7) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/120.0.0.0 Safari/537.36',
            'sec-ch-ua': '"Not_A Brand";v="8", "Chromium";v="120", "Google Chrome";v="120"',
            'sec-ch-ua-mobile': '?0',
            'sec-ch-ua-platform': '"macOS"'
          }
        }
      )
    ).pipe(
      map(res => {
        if (!res.data?.data?.token) {
          ILogger.info(`Upload video pre failed: ${JSON.stringify(res.data)}`)
          throw new HttpException("Upload video pre failed.", HttpStatus.BAD_REQUEST)
        }
        task.res_uploadVideo.res_uploadVideo_pre = res.data
        return task
      })
    )
  }

  uploadVideo_resume(task: IWonewSer.KsPublishTask) {
    const uploadToken: string = this.getUploadToken(task)
    return defer(() => 
      axios.get('https://upload.kuaishouzt.com/api/upload/resume', {
        params: {
          'upload_token': uploadToken,
        },
        headers: {
          'Accept': 'application/json, text/plain, */*',
          'Accept-Language': 'zh-CN,zh;q=0.9',
          'Cache-Control': 'no-cache',
          'Connection': 'keep-alive',
          'Origin': 'https://cp.kuaishou.com',
          'Pragma': 'no-cache',
          'Referer': 'https://cp.kuaishou.com/',
          'Sec-Fetch-Dest': 'empty',
          'Sec-Fetch-Mode': 'cors',
          'Sec-Fetch-Site': 'cross-site',
          'User-Agent': 'Mozilla/5.0 (Macintosh; Intel Mac OS X 10_15_7) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/120.0.0.0 Safari/537.36',
          'sec-ch-ua': '"Not_A Brand";v="8", "Chromium";v="120", "Google Chrome";v="120"',
          'sec-ch-ua-mobile': '?0',
          'sec-ch-ua-platform': '"macOS"'
        }
      })
    ).pipe(
      map(res => {
        if (res.data?.result !== 1) {
          ILogger.info(`Upload video resume failed: ${JSON.stringify(res.data)}`)
          throw new HttpException("Upload video resume failed.", HttpStatus.BAD_REQUEST)
        }
        task.res_uploadVideo.res_uploadVideo_resume = res.data
        return task
      })
    )
  }

  uploadVideo_upload(task: IWonewSer.KsPublishTask) {
    let prePartLength: number = 4194304
    const totalCount: number = Math.ceil(task.videoBuffer.length / prePartLength)
    const parts: IWonewSer.KsUploadPart[] = IHelper.getArray(totalCount).map(idx => {
      const partBuffer = task.videoBuffer.subarray(idx * prePartLength, (idx + 1) * prePartLength);
      return {
        idx: idx.toString(),
        buffer: partBuffer,
      }
    })
    return concat(
      ...parts.map(part => this.uploadVideo_uploadPrePart(task, part))
    ).pipe(
      reduce((ls, acc) => [...ls, acc], []),
      map(res => {
        task.res_uploadVideo.res_uploadVideo_fragment = res
        return task
      })
    )
  }

  uploadVideo_uploadPrePart(task: IWonewSer.KsPublishTask, part: IWonewSer.KsUploadPart) {
    const uploadToken = this.getUploadToken(task)
    return of(null).pipe(
      tap(() => ILogger.info(`${task.uuid} uploadVideo_uploadPrePart ${part.idx} start`)),
      concatMap(() => 
        axios.post(
          'https://upload.kuaishouzt.com/api/upload/fragment',
          part.buffer,
          {
            params: {
              'upload_token': uploadToken,
              'fragment_id': part.idx
            },
            headers: {
              'Accept': 'application/json, text/plain, */*',
              'Accept-Language': 'zh-CN,zh;q=0.9',
              'Cache-Control': 'no-cache',
              'Connection': 'keep-alive',
              'Content-Range': 'bytes 0-4194303/14404497',
              'Content-Type': 'application/octet-stream',
              'Origin': 'https://cp.kuaishou.com',
              'Pragma': 'no-cache',
              'Referer': 'https://cp.kuaishou.com/',
              'Sec-Fetch-Dest': 'empty',
              'Sec-Fetch-Mode': 'cors',
              'Sec-Fetch-Site': 'cross-site',
              'User-Agent': 'Mozilla/5.0 (Macintosh; Intel Mac OS X 10_15_7) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/120.0.0.0 Safari/537.36',
              'sec-ch-ua': '"Not_A Brand";v="8", "Chromium";v="120", "Google Chrome";v="120"',
              'sec-ch-ua-mobile': '?0',
              'sec-ch-ua-platform': '"macOS"'
            }
          }
        )
      ),
      map(res => {
        ILogger.info(`${task.uuid} uploadVideo_uploadPrePart ${part.idx} end`)
        if (res.data?.result !== 1) {
          ILogger.info(`uploadVideo_uploadPrePart part idx: ${JSON.stringify(res.data)}`)
          throw new HttpException(`uploadVideo_uploadPrePart part idx: ${part.idx} failed`, HttpStatus.BAD_REQUEST)
        }
        return res.data
      })
    )
    // return defer(() => 
      
    // ).pipe(
      
    // )
  }

  uploadVideo_complete(task: IWonewSer.KsPublishTask) {
    const uploadToken = this.getUploadToken(task)
    const fragment_count = this.getUploadFragmentCount(task)
    return defer(() => 
      axios.post(
        'https://upload.kuaishouzt.com/api/upload/complete',
        '',
        {
          params: {
            'fragment_count': fragment_count.toString(),
            'upload_token': uploadToken
          },
          headers: {
            'Accept': 'application/json, text/plain, */*',
            'Accept-Language': 'zh-CN,zh;q=0.9',
            'Cache-Control': 'no-cache',
            'Connection': 'keep-alive',
            'Content-Length': '0',
            'Origin': 'https://cp.kuaishou.com',
            'Pragma': 'no-cache',
            'Referer': 'https://cp.kuaishou.com/',
            'Sec-Fetch-Dest': 'empty',
            'Sec-Fetch-Mode': 'cors',
            'Sec-Fetch-Site': 'cross-site',
            'User-Agent': 'Mozilla/5.0 (Macintosh; Intel Mac OS X 10_15_7) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/120.0.0.0 Safari/537.36',
            'sec-ch-ua': '"Not_A Brand";v="8", "Chromium";v="120", "Google Chrome";v="120"',
            'sec-ch-ua-mobile': '?0',
            'sec-ch-ua-platform': '"macOS"'
          }
        }
      )
    ).pipe(
      map(res => {
        if (res.data?.result !== 1) {

          ILogger.info(`uploadVideo_complete: ${JSON.stringify(res.data)}`)
          throw new HttpException(`uploadVideo_complete failed`, HttpStatus.BAD_REQUEST)
        }
        task.res_uploadVideo.res_uploadVideo_complete = res.data
        return task
      })
    )
  }

  uploadVideo_finish(task: IWonewSer.KsPublishTask) {
    const uploadToken = this.getUploadToken(task)
    return defer(() => 
      axios.post(
        'https://cp.kuaishou.com/rest/cp/works/v2/video/pc/upload/finish',
        {
          'token': uploadToken,
          'fileName': `${IHelper.hash(32)}.${task.videoFiletype.ext}`,
          'fileType': task.videoFiletype.mime,
          'fileLength': task.videoBuffer.length,
          'kuaishou.web.cp.api_ph': this.getApiPh(task),
        },
        {
          headers: {
            'Accept': '*/*',
            'Accept-Language': 'zh-CN,zh;q=0.9',
            'Cache-Control': 'no-cache',
            'Connection': 'keep-alive',
            'Content-Type': 'application/json;charset=UTF-8',
            'Cookie': IHelper.covert2StandardCookieStr(task.accountSchema.cookie),
            'Origin': 'https://cp.kuaishou.com',
            'Pragma': 'no-cache',
            'Referer': 'https://cp.kuaishou.com/article/publish/video',
            'Sec-Fetch-Dest': 'empty',
            'Sec-Fetch-Mode': 'cors',
            'Sec-Fetch-Site': 'same-origin',
            'User-Agent': 'Mozilla/5.0 (Macintosh; Intel Mac OS X 10_15_7) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/120.0.0.0 Safari/537.36',
            'sec-ch-ua': '"Not_A Brand";v="8", "Chromium";v="120", "Google Chrome";v="120"',
            'sec-ch-ua-mobile': '?0',
            'sec-ch-ua-platform': '"macOS"'
          }
        }
      )
    ).pipe(
      map(res => {
        if (res.data?.result !== 1) {
          ILogger.info(`uploadVideo_finish failed: ${JSON.stringify(res.data)}`)
          throw new HttpException(`uploadVideo_finish failed`, HttpStatus.BAD_REQUEST)
        }
        task.res_uploadVideo.res_uploadVideo_finish = res.data
        return task
      })
    )
  }

  uploadCover_upload(task: IWonewSer.KsPublishTask) {
    const formData = new FromData()
    formData.append("kuaishou.web.cp.api_ph", this.getApiPh(task))
    const coverPath = IHelper.getAssetAbsPathByStaticPath(task.videoSchema.cover)
    formData.append("file", fs.createReadStream(coverPath))
    return defer(() => 
      axios.post(
        'https://cp.kuaishou.com/rest/cp/works/v2/video/pc/upload/cover/upload',
        formData,
        {
          headers: {
            'Host': 'cp.kuaishou.com',
            'Pragma': 'no-cache',
            'Cache-Control': 'no-cache',
            'sec-ch-ua': '"Not_A Brand";v="8", "Chromium";v="120", "Google Chrome";v="120"',
            'sec-ch-ua-platform': '"macOS"',
            'sec-ch-ua-mobile': '?0',
            'User-Agent': 'Mozilla/5.0 (Macintosh; Intel Mac OS X 10_15_7) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/120.0.0.0 Safari/537.36',
            'Content-Type': 'multipart/form-data; boundary=----WebKitFormBoundaryb25BhDxBBBzwvaB9',
            'Accept': '*/*',
            'Origin': 'https://cp.kuaishou.com',
            'Sec-Fetch-Site': 'same-origin',
            'Sec-Fetch-Mode': 'cors',
            'Sec-Fetch-Dest': 'empty',
            'Referer': 'https://cp.kuaishou.com/article/publish/video',
            'Accept-Language': 'zh-CN,zh;q=0.9',
            'Cookie': IHelper.covert2StandardCookieStr(task.accountSchema.cookie),
            ...formData.getHeaders(),
          }
        }
      )
    ).pipe(
      map(res => {
        if (res.data?.result !== 1) {
          ILogger.info(`Upload cover failed ${JSON.stringify(res.data)}`)
          throw new HttpException(`Upload cover failed.`, HttpStatus.BAD_REQUEST)
        }
        task.res_uploadCover.res_uploadCover_upload = res.data
        return task
      })
    )
  }

  buildConfigs(task: IWonewSer.KsPublishTask) {
    const [domain, secondDomain] = (task.taskSchema.ks_type || "").split("_")
    const tags = task.taskSchema.common_tag.split(",").filter(e => e).map(e => `#${e}`)
    return {
      caption: [task.taskSchema.title, ...tags].join(" "),
      domain,
      secondDomain,
    }
  }

  publishVideo(task: IWonewSer.KsPublishTask) {
    const uri: string = `https://cp.kuaishou.com/rest/cp/works/v2/video/pc/submit`
    const headers: RawAxiosRequestHeaders = {
      'Accept': '*/*',
            'Accept-Language': 'zh-CN,zh;q=0.9',
            'Cache-Control': 'no-cache',
            'Connection': 'keep-alive',
            'Content-Type': 'application/json;charset=UTF-8',
            'Cookie': IHelper.covert2StandardCookieStr(task.accountSchema.cookie),
            'Origin': 'https://cp.kuaishou.com',
            'Pragma': 'no-cache',
            'Referer': 'https://cp.kuaishou.com/article/publish/video',
            'Sec-Fetch-Dest': 'empty',
            'Sec-Fetch-Mode': 'cors',
            'Sec-Fetch-Site': 'same-origin',
            'User-Agent': 'Mozilla/5.0 (Macintosh; Intel Mac OS X 10_15_7) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/120.0.0.0 Safari/537.36',
            'sec-ch-ua': '"Not_A Brand";v="8", "Chromium";v="120", "Google Chrome";v="120"',
            'sec-ch-ua-mobile': '?0',
            'sec-ch-ua-platform': '"macOS"'
    }
    const postData: any = {
      'fileId': task.res_uploadVideo.res_uploadVideo_finish.data.fileId,
      'coverKey': task.res_uploadCover.res_uploadCover_upload.data.coverKey,
      'coverTimeStamp': -1,
      'caption': '\u641E\u7B11\u89C6\u9891\xA0#\u641E\u7B11\u89C6\u9891\xA0',
      'domain': '\u641E\u7B11',
      'secondDomain': '\u641E\u7B11\u6BB5\u5B50',
      'photoStatus': 1,
      'coverType': 2,
      'coverTitle': '',
      'photoType': 0,
      'collectionId': '',
      'publishTime': 0,
      'longitude': '',
      'latitude': '',
      'notifyResult': 0,
      'coverCropped': true,
      'pkCoverKey': '',
      'downloadType': 1,
      'disableNearbyShow': false,
      'allowSameFrame': true,
      'movieId': '',
      'openPrePreview': false,
      'declareInfo': {},
      'projectId': '',
      'recTagIdList': [],
      'videoInfoMeta': '',
      'previewUrlErrorMessage': '',
      'triggerH265': false,
      'mediaId': task.res_uploadVideo.res_uploadVideo_finish.data.mediaId,
      'photoIdStr': task.res_uploadVideo.res_uploadVideo_finish.data.photoIdStr,
      'videoDuration': task.res_uploadVideo.res_uploadVideo_finish.data.videoDuration,
      'kuaishou.web.cp.api_ph': this.getApiPh(task),
      ...this.buildConfigs(task),
    }
    return defer(() => 
      axios.post(uri, postData, { headers })
    ).pipe(
      map(res => {
        ILogger.info(`publishVideo :${JSON.stringify(res.data)}`)
        task.res_publishVideo = res.data
        return task
      })
    )
  }

  deleteArt(photoId: string) {
    return defer(() => 
      axios.post(
        'https://cp.kuaishou.com/rest/cp/works/v2/video/pc/delete',
        {
          'photoId': photoId || '3xae22nrqi7f9vs',
          'kuaishou.web.cp.api_ph': '796a1f8b338adfe6ceaabf3e1d573becb006'
        },
        {
          params: {
            '__NS_sig3': '2a3a7d4dd419c01ce4777475421b2b5faf4be30f6b6b69696667647e'
          },
          headers: {
            'Accept': 'application/json, text/plain, */*',
            'Accept-Language': 'zh-CN,zh;q=0.9',
            'Cache-Control': 'no-cache',
            'Connection': 'keep-alive',
            'Content-Type': 'application/json;charset=UTF-8',
            'Cookie': 'did=web_4a1f1b15990c8a12386d53fa4ada92b0; userId=3295875823; kuaishou.web.cp.api_st=ChZrdWFpc2hvdS53ZWIuY3AuYXBpLnN0EqABW_T5lIOdTNQz9t1vEfHbq3ViT4EmqrFqE-r5jGsZ0GVfgy6yyia3poEtvj_Bclp3H4gtr2gwGuFdN34sOMuGh6uctPfRphzUsTSJJ8lRFsziORV3hpmVTwI2ufnUQym2Ff3KgC5yKvYr3K8yrdogjg-fvsBtsxwNlcgiEydkxjXtmbw-trJK5HX3NnfYZUSJlUgoVhMW7VXA4b5L6Xx6pBoSPRRvGtXySX7EnaufBy__uLw_IiAKIFO4TnDN30nezCTzG3gQOqpcIL5A-wyWg35Dezjc6igFMAE; kuaishou.web.cp.api_ph=796a1f8b338adfe6ceaabf3e1d573becb006; language=zh-CN',
            'Origin': 'https://cp.kuaishou.com',
            'Pragma': 'no-cache',
            'Referer': 'https://cp.kuaishou.com/article/manage/video?status=2&from=publish',
            'Sec-Fetch-Dest': 'empty',
            'Sec-Fetch-Mode': 'cors',
            'Sec-Fetch-Site': 'same-origin',
            'User-Agent': 'Mozilla/5.0 (Macintosh; Intel Mac OS X 10_15_7) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/120.0.0.0 Safari/537.36',
            'X-Requested-With': 'XMLHttpRequest',
            'returnSetRootDomainLoginUrl': 'true',
            'sec-ch-ua': '"Not_A Brand";v="8", "Chromium";v="120", "Google Chrome";v="120"',
            'sec-ch-ua-mobile': '?0',
            'sec-ch-ua-platform': '"macOS"'
          }
        }
      )
    ).pipe(
      map(res => res.data)
    )
  }

  suggestTag(keyword: string) {
    const user = this.reqProvider.user
    return defer(() => 
      this.dbService.accountRepository.findOneByOrFail({uid: user.id, type: 3, status: 1})
    ).pipe(
      concatMap(accountSchema => 
        this.ksBindService.checkCookie(accountSchema?.cookie).pipe(
          map(({valid}) => {
            if (!valid) {
              throw new HttpException(`Cookie expired.`, HttpStatus.BAD_REQUEST)
            }
            return accountSchema
          })
        )
      ),
      concatMap(accountSchema => {
        return axios.post(
          'https://cp.kuaishou.com/rest/cp/works/v2/video/pc/tag/search',
          {
            'count': 15,
            'keyword': keyword,
            'page': '0',
            'kuaishou.web.cp.api_ph': this.getApiPh({accountSchema} as IWonewSer.KsPublishTask)
          },
          {
            headers: {
              'Accept': '*/*',
              'Accept-Language': 'zh-CN,zh;q=0.9',
              'Cache-Control': 'no-cache',
              'Connection': 'keep-alive',
              'Content-Type': 'application/json;charset=UTF-8',
              'Cookie': IHelper.covert2StandardCookieStr(accountSchema.cookie),
              'Origin': 'https://cp.kuaishou.com',
              'Pragma': 'no-cache',
              'Referer': 'https://cp.kuaishou.com/article/publish/video',
              'Sec-Fetch-Dest': 'empty',
              'Sec-Fetch-Mode': 'cors',
              'Sec-Fetch-Site': 'same-origin',
              'User-Agent': 'Mozilla/5.0 (Macintosh; Intel Mac OS X 10_15_7) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/120.0.0.0 Safari/537.36',
              'sec-ch-ua': '"Not_A Brand";v="8", "Chromium";v="120", "Google Chrome";v="120"',
              'sec-ch-ua-mobile': '?0',
              'sec-ch-ua-platform': '"macOS"'
            }
          }
        ).then(res => res.data)
      })
    )
  }
  // 分类
  getTypeList() {
    const user = this.reqProvider.user
    return defer(() => 
      this.dbService.accountRepository.findOneByOrFail({uid: user.id, type: 3, status: 1})
    ).pipe(
      concatMap(accountSchema => 
        this.ksBindService.checkCookie(accountSchema?.cookie).pipe(
          map(({valid}) => {
            if (!valid) {
              throw new HttpException(`Cookie expired.`, HttpStatus.BAD_REQUEST)
            }
            return accountSchema
          })
        )
      ),
      concatMap(accountSchema => {
        return axios.post(
          'https://cp.kuaishou.com/rest/cp/works/v2/video/pc/upload/domain/list',
          {
            'kuaishou.web.cp.api_ph': this.getApiPh({accountSchema} as IWonewSer.KsPublishTask)
          },
          {
            headers: {
              'Accept': '*/*',
              'Accept-Language': 'zh-CN,zh;q=0.9',
              'Cache-Control': 'no-cache',
              'Connection': 'keep-alive',
              'Content-Type': 'application/json;charset=UTF-8',
              'Cookie': IHelper.covert2StandardCookieStr(accountSchema.cookie),
              'Origin': 'https://cp.kuaishou.com',
              'Pragma': 'no-cache',
              'Referer': 'https://cp.kuaishou.com/article/publish/video',
              'Sec-Fetch-Dest': 'empty',
              'Sec-Fetch-Mode': 'cors',
              'Sec-Fetch-Site': 'same-origin',
              'User-Agent': 'Mozilla/5.0 (Macintosh; Intel Mac OS X 10_15_7) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/120.0.0.0 Safari/537.36',
              'sec-ch-ua': '"Not_A Brand";v="8", "Chromium";v="120", "Google Chrome";v="120"',
              'sec-ch-ua-mobile': '?0',
              'sec-ch-ua-platform': '"macOS"'
            }
          }
        ).then(res => res.data.data)
      }),
      timeout(1500),
      catchError(() => {
        return of(
          JSON.parse(fs.readFileSync(path.join(__dirname, "json/ks_typelist.json"), "utf-8"))
        )
      }),
      map(res => IResponse.success(res))
    )
  }

  getUploadToken(task: IWonewSer.KsPublishTask): string {
    return task.res_uploadVideo?.res_uploadVideo_pre?.data?.token || ""
  }

  getUploadFragmentCount(task: IWonewSer.KsPublishTask): number {
    return task.res_uploadVideo.res_uploadVideo_fragment.length
  }
}